package main

import (
	"fmt"
	"github.com/PhlexTheCharr/gofurry-cloud-service/common"
	cs "github.com/PhlexTheCharr/gofurry-cloud-service/common/service"
	"github.com/PhlexTheCharr/gofurry-cloud-service/middleware"
	"github.com/PhlexTheCharr/gofurry-cloud-service/roof/env"
	"github.com/PhlexTheCharr/gofurry-cloud-service/routers"
	"github.com/gofiber/fiber/v2/log"
	"github.com/kardianos/service"
	"os"
	"os/signal"
	"runtime/debug"
	"syscall"
)

//@title GoFurry-Cloud
//@version v1.0.0
//@description GoFurry-Cloud

var (
	errChan = make(chan error)
	err     error
)

func main() {
	dir, _ := os.Getwd()

	svcConfig := &service.Config{
		Name:        common.COMMON_PROJECT_NAME,
		DisplayName: "gf-cloud",
		Description: "gf-cloud",
		Option: service.KeyValue{
			"SystemdScript": `[Unit]
Description=gf-cloud (自定义配置)
After=network.target
Requires=network.target

[Service]
Type=simple
WorkingDirectory=` + dir + `/
ExecStart=` + dir + `/gf-cloud
Restart=always
RestartSec=30
LogOutput=true
LogDirectory=/var/log/gf-cloud
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target`,
		},
	}
	prg := &goFurry{}
	s, err := service.New(prg, svcConfig)
	if err != nil {
		log.Error(err)
	}

	if len(os.Args) > 1 {
		if os.Args[1] == "install" {
			s.Install()
			log.Info("服务安装成功.")
			return
		}

		if os.Args[1] == "uninstall" {
			s.Uninstall()
			log.Info("服务卸载成功.")
			return
		}
	}

	// 内存限制和 GC 策略
	debug.SetGCPercent(1000)
	debug.SetMemoryLimit(int64(env.GetServerConfig().Server.MemoryLimit << 30)) // 限制内存大小

	// 初始化系统服务
	InitOnStart()
	// 启动系统
	err = s.Run()
	if err != nil {
		log.Error(err)
	}
}

type goFurry struct{}

func InitOnStart() {
	// 初始化数据库
	cs.GetInitDB().InitDataBase()
	// 初始化 CorazaWAF
	err = middleware.InitCorazaWAF()
	if err != nil {
		log.Error(err)
	}
}

func (gf *goFurry) Start(s service.Service) error {
	go gf.run()
	return nil
}

func (gf *goFurry) run() {
	go func() {
		c := make(chan os.Signal)
		signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
		errChan <- fmt.Errorf("%s", <-c)
	}()
	// 启动 web
	go func() {

		app := routers.Router.Init()
		addr := env.GetServerConfig().Server.IPAddress + ":" + env.GetServerConfig().Server.Port
		pem := env.GetServerConfig().Key.TlsPem
		key := env.GetServerConfig().Key.TlsKey
		if err := app.ListenTLS(addr, pem, key); err != nil {
			fmt.Println(err)
			errChan <- err
		}
	}()
	if err := <-errChan; err != nil {
		log.Error(err)
	}
}

func (gf *goFurry) Stop(s service.Service) error {
	return nil
}
